﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net.Sockets; //使用Socket需要；
using System.Net; //使用IPAddress需要；
using System.Data.OleDb; //连接Access数据库用；
using System.Data;//CommandBehavior需要；

namespace OrderFood_WPF
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public class Food
    {
        public string food_name;
        public float food_price;
        public string food_pic_url;
        public bool food_type;

        public Food(string food_name, float food_price, string food_pic_url, bool food_type)
        {
            this.food_name = food_name;
            this.food_price = food_price;
            this.food_pic_url = food_pic_url;
            this.food_type = food_type;
        }
    }
    public struct Order
    {
        public string user_name;
        public string user_phone;
        public string addr_building;
        public string addr_dormitory;
        public float order_price;
        public string detail;
    }
    public struct Packet
    {
        public Header header;
        public Order order;
    }
    public struct Header
    {
        //int len;
        public int type;
    }
    public partial class MainWindow : Window
    {
        //包类型；
        const int PKT_LOGIN = 0;
        const int PKT_LOGOUT = 1;
        const int PKT_ORDER = 2;

        Socket socket;
        OleDbConnection objConnection; //数据库连接；
        OleDbCommand sqlcmd; //数据库命令；
        OleDbDataReader reader; //读取的数据；
        public MainWindow()
        {
            InitializeComponent();
            //btn_load_Click(btn_load,new RoutedEventArgs() );//自动载入菜单；
        }
        private void showText(Label lab, string text)
        {
            lab.Content = text;
        }
        private void showLableOut(Label lab)
        {
            MessageBox.Show(mainWindow, lab.Content.ToString());
        }
        private void checkConnecte()
        {
            showText(lab_checkInfo, "处理IP和端口...");
            int port = System.Int32.Parse( tb_port.Text ); //取得端口号；
            string host = tb_ip.Text;
            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);//把ip和端口转化为IPEndPoint实例
            showText(lab_checkInfo, "创建Socket...");
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket

            showText(lab_checkInfo,"正尝试连接到服务器...");
            try
            {
                socket.Connect(ipe);//连接到服务器
                showText(lab_checkInfo, "已与服务器建立连接！可以订餐！");
            }
            catch (ArgumentNullException ex)
            {
                showText(lab_checkInfo, "不能订餐！IP或端口错误。" + ex);
            }
            catch (SocketException ex)
            {
                showText(lab_checkInfo, "不能订餐！尝试访问套接字时发生错误。" + ex);
            }
            catch (ObjectDisposedException ex)
            {
                showText(lab_checkInfo, "不能订餐！Socket 已关闭。" + ex);
            }
            
        }
        private void btn_check_Click(object sender, RoutedEventArgs e)
        {
            checkConnecte();
        }

        private void lab_checkInfo_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            showLableOut(lab_checkInfo);
        }
        private void btn_load_Click(object sender, RoutedEventArgs e)
        {
            bool isGotDB = false; //是否成功连接数据库；
            try
            { //连接数据库；
                //构造连接字符串
                string strConnection = "Provider=Microsoft.Jet.OleDb.4.0;";
                string filePath = System.Environment.CurrentDirectory + "\\db.mdb";
                strConnection += "Data Source=" + filePath;

                objConnection = new OleDbConnection(strConnection);  //建立连接
                objConnection.Open();  //打开连接

                showText(lab_db, "数据库打开成功！");
                isGotDB = true;
            }
            catch (OleDbException er)
            {
                showText(lab_db, "数据库连接出错！" + er.Message);
            }
            if (isGotDB)
            {
                wrapPanal_food.Children.Clear();
                wp_ordered.Children.Clear();
                lab_nDish.Content = "0";
                lab_howMuch.Content = "0";
                showFood(10); //载入8道菜；
            }
        }
        private void showFood(int n)
        {//生成并显示n道菜；
            try
            {
                sqlcmd = new OleDbCommand("select top " + n + " * from food ORDER BY food_id DESC", objConnection);  //sql语句
                reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);  //执行查询，参数表示关闭dataReader 时,同时也把与它相关联的Connection连接也一起关闭；
                showText(lab_db, "数据库查询成功！");
                while (reader.Read())
                {//Read()使reader前进到下一条记录；
                    Food food = new Food(
                        reader.GetString(1),
                        reader.GetFloat(2),
                        reader.GetString(3),
                        reader.GetBoolean(4)
                        );//煮菜；
                    FoodControl fc = new FoodControl(food);//装盘；
                    wrapPanal_food.Children.Add(fc);//将菜放到桌上；
                }
            }
            catch (OleDbException ex)
            {
                showText(lab_db,ex.Message);
            }
            catch (InvalidCastException ex)
            {
                showText(lab_db, ex.Message);
            }
        }
        private void lab_db_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            showLableOut(lab_db);
        }
        private void btn_cal_Click(object sender, RoutedEventArgs e)
        {//结算按钮；
            int nDish = 0;
            float howMuch = 0.00F;
            UC_FoodBtn theBtn;
            foreach (UIElement element in wp_ordered.Children)
            {
                theBtn = (UC_FoodBtn)element;
                nDish++;
                howMuch += theBtn.fc.food.food_price;
            }
            lab_nDish.Content = nDish;
            lab_howMuch.Content = howMuch;
        }
        private void btn_send_Click(object sender, RoutedEventArgs e)
        {
            if (lab_nDish.Content.ToString().Equals("x"))
            {
                //lab_cal_info.Content = "请先进行结算！";
                MessageBox.Show(mainWindow, "请先进行结算！");
                return;
            }
            if (lab_nDish.Content.ToString().Equals("0"))
            {
                MessageBox.Show(mainWindow, "请至少订购一道菜！");
                return;
            }
            Order order;//订单；
            order.user_name = tb_userName.Text;
            order.user_phone = tb_userPhone.Text;
            order.addr_building = tb_building.Text;
            order.addr_dormitory = tb_dormitory.Text;
            if (order.user_name.Equals("") || order.user_phone.Equals("") || order.addr_building.Equals("") || order.addr_dormitory.Equals(""))
            {
                MessageBox.Show(mainWindow, "请填写完整您的信息！");
                return;
            }
            order.order_price = (float)lab_howMuch.Content;
            order.detail = getOrderDetail();

            Packet packet;
            packet.header.type = PKT_ORDER;
            packet.order = order;
            sendOrder(packet);
        }
        private void packetToBytes(Packet p,byte[] data)
        {
            int index = 0;
            Order order = p.order;
            byte[] type = BitConverter.GetBytes(p.header.type);
            byte[] user_name = Encoding.Default.GetBytes(order.user_name);
            byte[] user_phone = Encoding.Default.GetBytes(order.user_phone);
            byte[] addr_building = Encoding.Default.GetBytes(order.addr_building);
            byte[] addr_dormitory = Encoding.Default.GetBytes(order.addr_dormitory);
            byte[] order_price = Encoding.Default.GetBytes(order.order_price.ToString());
            byte[] detail = Encoding.Default.GetBytes(order.detail);

            if (BitConverter.IsLittleEndian)
            {//字节序问题；
                Array.Reverse(type);
                //Array.Reverse(order_price);
            }
            type.CopyTo(data, index);//数组拷贝；
            //index += type.Length;
            index += 4;
            user_name.CopyTo(data, index);
            index += 12;
            user_phone.CopyTo(data, index);
            index += 11;
            addr_building.CopyTo(data, index);
            index += 12;
            addr_dormitory.CopyTo(data, index);
            index += 5;
            order_price.CopyTo(data, index);
            index += 6;
            detail.CopyTo(data, index);
            //index += detail.Length;
        }
        private void sendOrder(Packet p)
        {
            lab_sendInfo.Content = "";

            byte[] data = new byte[512];
            packetToBytes(p, data);
            try
            {
                socket.Send(data, data.Length, 0);
                socket.Send(data, data.Length, 0);//发送第二次（测试需要）；

                lab_sendInfo.Content = "订单提交成功，请耐心等待工作人员送餐！";
            }
            catch (ArgumentException ex)
            {
                lab_sendInfo.Content = "参数存在错误！" + ex;
            }
            catch (SocketException ex)
            {
                lab_sendInfo.Content = "套接字错误！" + ex;
            }
            catch (ObjectDisposedException ex)
            {
                lab_sendInfo.Content = "对已释放的对象执行操作引发了错误！" + ex;
            }
        }       
        private string getOrderDetail()
        {//获得订单详情（全部菜名和价格）；
            string str = "";
            UC_FoodBtn theBtn;
            foreach (UIElement element in wp_ordered.Children)
            {
                theBtn = (UC_FoodBtn)element;
                str += "(" + theBtn.fc.food.food_name + "￥" + theBtn.fc.food.food_price + ")" + "*";
            }
            str = str.Substring(0, str.Length - 1);
            return str;
        }

        private void lab_sendInfo_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            showLableOut(lab_sendInfo);
        }
    }
}
